package com.zrzy.Test;

import com.zrzy.domain.Author;
import com.zrzy.domain.Book;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class OptionalDemo {
    public static void main(String[] args) {
        //测试 使用Optional一
/*        Author author = getAuthor();
        Optional<Author> authorOptional = Optional.ofNullable(author);//Optional创建对象
        authorOptional.ifPresent(author1 -> System.out.println("作家名字:"+author1.getName()));*/

        //测试 使用Optional一
        /*Optional<Author> authorOptional = getAuthorOptional();
        authorOptional.ifPresent(author -> System.out.println("作家名字:"+author.getName()));*/

        //测试 使用Optional一 的 of() 传入值 要非NUL
        /*Author author = getAuthor();
        Optional<Author> authorOptional1 = Optional.of(author);
        authorOptional1.ifPresent(value-> System.out.println("of的:"+value.getName()));*/

        //测试 使用Optional一 的 empty() 创建空的 Optional进行使用
        /*Optional<Object> empty = Optional.empty();
        empty.ifPresent(value-> System.out.println("empty的:"+value));*/

        //测试 Optional的 安全消费
        /*Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
        authorOptional.ifPresent(author -> System.out.println(author.getName()));*///消费操作

        //测试 安全的获取值
//        test01();

        //测试 过滤数据
//        test02();

        //测试 判断
//        test03();

        //测试 数据转换
        test04();
    }

    //测试 数据转换
    private static void test04() {
        //Optional还提供了map可以让我们的对数据进行转换，并且转换得到的数据也还是被Optional包装好的，保证了我们的使用安全
        Optional<Author> authorOptional = getAuthorOptional();
        // 把作者 转换 书籍
        Optional<List<Book>> books = authorOptional.map(author -> author.getBooks());
        books.ifPresent(books1 -> System.out.println(books1) );
    }

    //测试 判断
    private static void test03() {
        Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
        //使用isPresent方法进行是否存在数据的判断。如果为空返回值为false,如果不为空，返回值为true。
        if (authorOptional.isPresent()) {
            System.out.println(authorOptional.get().getName());
        }
    }

    //测试 过滤数据
    private static void test02() {
        Optional<Author> authorOptional = getAuthorOptional();

        //过滤器数据使用 filter方法 ,如果原本是有数据的，但是不符合判断，也会变成一个无数据的Optional对象。
        authorOptional.filter(author -> author.getAge() > 18)//要 18岁以上的 作家
                        .ifPresent(author -> System.out.println(author.getName()));

    }

    //测试 安全的获取值
    private static void test01() {
        Optional<Author> authorOptional = getAuthorOptional();
        //不推荐使用get方法 , 如果数据是 从数据库 查询出来的 有可能是 一个空的 Optional
        /*Author author = authorOptional.get();
        System.out.println(author.getName());*/

        //安全的获取值 orElseGet方法, 如果为空则根据你传入的参数来创建对象作为默认值返回
        /*Author author = authorOptional.orElseGet(() -> new Author(0L, "默认名称", 00, "默认名称", null));
        System.out.println(author.getName());*/

        //安全的获取值 orElseThrow方法 如果数据不为空就能获取到该数据。如果为空则根据你传入的参数来创建异常抛出
        try {
            Author author = authorOptional.orElseThrow(() -> new RuntimeException("数据为NULL"));
            System.out.println(author.getName());
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }

    //改造 getAuthor方法 返回Optional对象
    private static Optional<Author> getAuthorOptional() {
        //假设数据查出出来的数据
        Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);
        //书籍列表
        List<Book> books1 = new ArrayList<>();

        books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));
        books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理"));

        author.setBooks(books1);
        return Optional.ofNullable(author);
    }


    private static Author getAuthor() {
        Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);
        return author;
    }
}
